package com.mdp.tpa.wechat.service;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import com.mdp.tpa.wechat.HttpRequestUtil;
import com.mdp.tpa.wechat.api.cache.AccessTokenCache;
import com.mdp.tpa.wechat.config.WxpubProperties;
import com.mdp.tpa.wechat.entity.AccessToken;
import com.mdp.tpa.wechat.service.cache.DefaultAccessTokenCacheService;
import com.mdp.tpa.wechat.api.AccessTokenService;
import com.mdp.tpa.wechat.api.ApiUrls;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import com.mdp.core.err.BizException;

@Service
public class AccessTokenServiceImpl implements AccessTokenService {
	 
	Log log=LogFactory.getLog(AccessTokenServiceImpl.class);
	private  Lock lock = new ReentrantLock();

	@Autowired
	WxpubProperties properties;
	 
	DefaultAccessTokenCacheService defaultCache=new DefaultAccessTokenCacheService();
	
	@Autowired(required=false)
	AccessTokenCache cache=defaultCache;
	 
	
	@Value("${mdp.wxapi.enabled-load-access-token:true}")
	boolean enabledLoadAccessToken=true;

	@Override
	public AccessToken getAccessToken(String appid, String secret) {
		Map<String, Object> result= HttpRequestUtil.sendGetJson(String.format(ApiUrls.TOKEN, appid,secret), null);
		if(!result.containsKey("access_token")){
			log.error(result);
			log.error("获取access_token出错，将再尝试一次向微信获取access_token");
			 result=HttpRequestUtil.sendGetJson(String.format(ApiUrls.TOKEN, appid,secret), null);
		}
		if(!result.containsKey("access_token")){
			log.error(result);
			//log.error("获取access_token出错，将再尝试一次向微信获取access_token");
			//result=swapTemplate.send("wxapi_accessToken_getSnsOauth2AccessToken", map);
			throw new BizException(result.get("errcode")+"", (String) result.get("errmsg"));
		}
		AccessToken token=new AccessToken();
		token.setAccessToken((String) result.get("access_token"));
		token.setExpiresIn((Integer) result.get("expires_in"));
		Date now=new Date();
		token.setCtime(now.getTime());
		cache.put(appid, token);
		return token;
	}



	@Override
	public String getToken() {
		return getAccessToken().getAccessToken();
	}


	@Override
	public AccessToken getAccessToken() {
		AccessToken accessToken;
		lock.lock();
		try {
			String appid=properties.getAppid();
			accessToken = cache.get(appid);
			if (accessToken == null) {

				String appSecret = properties.getAppSecret();
				accessToken = this.getAccessToken(appid, appSecret);
			} 
		} finally {
			lock.unlock();
		}
		return accessToken;
	}

 
 
	@Scheduled(fixedRate=AccessTokenCache.TokenCheckMilliseconds,initialDelay=60000)
	void checkAccessToken(){  
		
		try { 
			if( this.enabledLoadAccessToken==false) {
				log.info("不执行accessToken的更新 enabledLoadAccessToken="+this.enabledLoadAccessToken);
				return;
			}

					try {
						Date now=new Date();
						Long time=now.getTime();
						AccessToken accessToken=cache.get(properties.getAppid());
						String appSecret=properties.getAppSecret();
							if(accessToken==null|| (time-accessToken.getCtime() + AccessTokenCache.TokenCheckMilliseconds*2) >= accessToken.getExpiresIn()*1000 ){
								getAccessToken(properties.getAppid(),appSecret);
							}
						
						
					} catch (Exception e) {
						log.error("自动检查刷新微信accessToken是否过期失败 应用编号【"+properties.getAppid()+"】");
					}
		} catch (Exception e) {
			log.error("自动检查刷新微信accessToken是否过期失败"); 
		}
			
		 
	}
 
}
